﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
namespace Estimate.Common.Estimate
{
    /// <summary>
    /// 温度评分
    /// </summary>
    public class TempScore
    {
        /// <summary>
        /// 温度分数
        /// </summary>
        [JsonIgnore]
        public List<float> OffsetList = new List<float>();

        /// <summary>
        /// 空预报
        /// </summary>
        public int EmptyForecast = 0;

        /// <summary>
        /// 预报少于stationmatch里的站点
        /// </summary>
        public int LackForecast = 0;

        /// <summary>
        /// 实况错误数据。错就是温度如何大于45度，小于-15度就是错的
        /// </summary>
        public int RealError = 0;

        /// <summary>
        /// 预报错误数据。错就是温度如何大于45度，小于-15度就是错的
        /// </summary>
        public int ForecastError = 0;

        /// <summary>
        /// 实况少于stationmatch里的站点
        /// </summary>
        public int LackReal = 0;

        /// <summary>
        /// 实况值为9999
        /// </summary>
        public int EmptyReal = 0;


        /// <summary>
        /// 温度平均误差
        /// </summary>
        /// <returns>误差值</returns>
        public float CalTmae()
        {
            if (OffsetList.Count > 0)
            {
                float all = 0f;
                foreach (float f in OffsetList)
                {
                    all += Math.Abs(f);
                }
                return all / OffsetList.Count;
            }
            else
                return 0f;
        }

        /// <summary>
        /// 温度平均误差
        /// </summary>
        public float Tame
        {
            get
            {
                return CalTmae();
            }
        }

        /// <summary>
        /// 温度均方根误差
        /// </summary>
        /// <returns></returns>
        public float CalTrmse()
        {            
            if (OffsetList.Count > 0)
            {
                float all = 0f;
                foreach (float f in OffsetList)
                {
                    all += Math.Abs(f); 
                }
                return (float)Math.Sqrt(all / OffsetList.Count);
            }
            else
                return 0f;
        }


        /// <summary>
        /// 温度均方根误差
        /// </summary>
        public float Trmse
        {
            get
            {
                return CalTrmse();
            }
        }

        /// <summary>
        /// 温度预报准确率(k:误差小于1或2度)
        /// </summary>
        /// <param name="k">误差</param>
        /// <returns></returns>
        public float Tt(int k)
        {
            if (OffsetList.Count > 0)
            {
                float all = 0f;
                foreach (float f in OffsetList)
                {
                    if (Math.Abs(f) <= k)
                        all += 1;
                }
                return all / OffsetList.Count * 100f;
            }
            else
                return 0f;
        }

        /// <summary>
        /// 温度预报准确率(误差小于2度)
        /// </summary>
        public float Tt2
        {
            get
            {
                return this.Tt(2);
            }
        }

        /// <summary>
        /// 温度预报准确率(误差小于1度)
        /// </summary>
        public float Tt1
        {
            get
            {
                return this.Tt(1);
            }
        }

        public override string ToString()
        {
            List<string> offsetStringList = new List<string>(OffsetList.Count);
            foreach (float f in OffsetList)
            {
                offsetStringList.Add(string.Format("{0:0.00}", f));
            }
            string strOffset = "empty";
            if( offsetStringList.Count > 0)
               strOffset = string.Join("_", offsetStringList.ToArray());
            
            return string.Format("{0},{1},{2},{3},{4},{5},{6}", new object[]{
                        strOffset,
                        EmptyForecast,
                        LackForecast,
                        ForecastError,
                        RealError,
                        LackReal,
                        EmptyReal,
                    });
        }

        public void FromString(string value)
        {
            OffsetList.Clear();
            string[] valueArray = Regex.Split(value, @"\,");
            if (valueArray[0] != "empty")
            {
                string[] strOffset = Regex.Split(valueArray[0], @"_");
                foreach (string s in strOffset)
                {
                    OffsetList.Add(Convert.ToSingle(s));
                }
            }

            EmptyForecast = Convert.ToInt32(valueArray[1]);
            LackForecast = Convert.ToInt32(valueArray[2]);
            ForecastError = Convert.ToInt32(valueArray[3]);
            RealError = Convert.ToInt32(valueArray[4]);
            LackReal = Convert.ToInt32(valueArray[5]);
            EmptyReal = Convert.ToInt32(valueArray[6]);
        }

        public void Add(TempScore score)
        {
            
            foreach (float offset in score.OffsetList)
                OffsetList.Add(offset);

            EmptyForecast += score.EmptyForecast;
            LackForecast += score.LackForecast;
            RealError += score.RealError;
            ForecastError += score.ForecastError;
            LackReal += score.LackReal;
            EmptyReal += score.EmptyReal;
        }
    }
}
